package academic.ui.client.view;



import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import ui.client.GenericClickable;
import ui.client.GenericContainerTag;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RadioButton;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.gwtplatform.mvp.client.ViewImpl;


import academic.ui.client.config.CSSConstants;
import academic.ui.client.jquery.JQuery;
import academic.ui.client.presenter.CardPresenter;
import academic.ui.client.widgets.forms.AddEditCCForm;
import ecommerce.soco.shared.GWT_CreditCard;
import ecommerce.soco.shared.GWT_Zone;

public class CardView extends ViewImpl implements CardPresenter.MyView {

	private String context="";
	private GenericContainerTag paymentMethodTbl = new GenericContainerTag("div");
	
	//maps payment details ID to fields
	private Map<String,GWT_CreditCard> cardMap= new HashMap<String,GWT_CreditCard>();
	private Map<String,GenericContainerTag> editDivMap = new HashMap<String,GenericContainerTag>();
	private GenericContainerTag myCardsDiv = new GenericContainerTag("div");
	private AddEditCCForm ccForm = new AddEditCCForm();
	
	
	@Inject
	public CardView(CSSConstants css) {
		paymentMethodTbl.setStyleName("checkout");
		GenericContainerTag ccLabel = new GenericContainerTag("span","Credit Cards:");
		ccLabel.setStyleName("ccLabel");
		myCardsDiv.setStyleName("myCardsDiv");
		paymentMethodTbl.add(ccLabel);
		paymentMethodTbl.add(addCard);
		paymentMethodTbl.add(addCardDiv);
		paymentMethodTbl.add(myCardsDiv);
		GenericContainerTag saveDefaultDiv = new GenericContainerTag("div");
		saveDefaultDiv.setStyleName("saveDefaultDiv");
		//saveDefaultDiv.add(saveDefaultCard);
		
		paymentMethodTbl.add(saveDefaultDiv);
		
		addCardDiv.clear();
		
		addCardDiv.add(insertCard);
		Button cancel = new Button("cancel");
		addCardDiv.add(cancel);
		cancel.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				addCardDiv.setVisible(false);
				addCard.setVisible(true);
			}		
		});
	}
	
	
	@Override
	public Widget asWidget() {
		return paymentMethodTbl;
	}
	
	private ArrayList<HasClickHandlers> editCardHandlers = new ArrayList<HasClickHandlers>();
	private ArrayList<HasClickHandlers> removeCardHandlers = new ArrayList<HasClickHandlers>();
	private Map<String,RadioButton> radioValues = new HashMap<String,RadioButton>();
	
	private Button addCard = new Button("add card");
	
	private GenericContainerTag addCardDiv = new GenericContainerTag("div");

	//private Button saveDefaultCard = new Button("save selected card as my default");

	@Override
	public void setup(GWT_CreditCard[] paymentDetails) {
		addCardDiv.setVisible(false);
		
		addCard.setVisible(true);
		ccForm.setVisible(false);
		ccForm.removeErrors();
		myCardsDiv.clear();
		//saveDefaultCard.setVisible(false);

		radioValues.clear();
		editCardHandlers.clear();
		removeCardHandlers.clear();
		editDivMap.clear();
		cardMap.clear();
		for (int i = 0; i < paymentDetails.length; i++) {
			//set the radio label to be the card type (ie, Visa)
			GenericContainerTag aPaymentOptionDiv = new GenericContainerTag("div");
			RadioButton rbutton = new RadioButton("paymentOption", paymentDetails[i].getCcType());
			rbutton.setValue(paymentDetails[i].getIsDefault());
			radioValues.put(String.valueOf(paymentDetails[i].getCreditCardId()),rbutton);
			rbutton.getElement().setId(String.valueOf(paymentDetails[i].getCreditCardId()));
			if(paymentDetails[i].getIsDefault())
				rbutton.addStyleName("radioSelected");
			rbutton.addValueChangeHandler(new ValueChangeHandler<Boolean>() {

				@Override
				public void onValueChange(ValueChangeEvent<Boolean> event) {
					
					for(RadioButton rb : radioValues.values())
						rb.removeStyleName("radioSelected");
					if(event.getValue())
						((Widget)event.getSource()).addStyleName("radioSelected");
					
				}
				
			});
			
			
			aPaymentOptionDiv.add(rbutton);
			
			//TODO: only send the last four digits from the server 
			Integer cardNumLength=paymentDetails[i].getCcNumber().length();
			GenericContainerTag creditCardValueLbl = new GenericContainerTag("span", "xxxx-"+ paymentDetails[i].getCcNumber().substring(cardNumLength-4, cardNumLength));
			creditCardValueLbl.setStyleName("accountSpan");
			aPaymentOptionDiv.add(creditCardValueLbl);
			
			//link used to open edit payment dialog
			GenericClickable editPayment = new GenericClickable("a","Modify");
			editCardHandlers.add(editPayment);

			editPayment.getElement().setId(String.valueOf(paymentDetails[i].getCreditCardId()));
		
			aPaymentOptionDiv.add(editPayment);
			
			//link used to remove payment
			if(!context.equals("checkout"))
			{	
				GenericClickable removePayment = new GenericClickable("a");
				removeCardHandlers.add(removePayment);
				removePayment.getElement().setInnerHTML("Remove");
				removePayment.setStyleName("remove");
				removePayment.getElement().setId(String.valueOf(paymentDetails[i].getCreditCardId()));
				aPaymentOptionDiv.add(removePayment);
			}
			GenericContainerTag editdetails = new GenericContainerTag("div");
			
			//id for this div not used for anything and can be removed if necessary
			editdetails.getElement().setId("editdetails"+paymentDetails[i].getCreditCardId());
			
			editDivMap.put(String.valueOf(paymentDetails[i].getCreditCardId()), editdetails);
			
			editdetails.setVisible(false);
			cardMap.put(String.valueOf(paymentDetails[i].getCreditCardId()), paymentDetails[i]);
				
			myCardsDiv.add(aPaymentOptionDiv);
			myCardsDiv.add(editdetails);
		}
		
				
	}
	
	
	
	@Override
	public void closeEditDialog(String id) {
		editDivMap.get(id).setVisible(false);
	}

	@Override
	public ArrayList<HasClickHandlers> editCardHandlers() {
		return editCardHandlers;
	}
	
	Button saveCard = new Button("save card");
	Button insertCard = new Button("Save Card");
	
	@Override
	public HasClickHandlers saveCard() {
		return saveCard;
	}


	@Override
	public void updateEditMode(String id) {
		addCardDiv.setVisible(false);
		final GenericContainerTag editdetails = editDivMap.get(id);
		GWT_CreditCard card = cardMap.get(id);
		editdetails.setVisible(true);
		ccForm.setVisible(true);
		editdetails.add(ccForm);
		addCard.setVisible(false);
		ccForm.removeErrors();
		ccForm.updateCard(card);
		
		editdetails.add(saveCard);
		saveCard.getElement().setId(id);
		Button cancel = new Button("cancel");
		editdetails.add(cancel);
		cancel.getElement().setId(id);
		cancel.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				editdetails.setVisible(false);
				addCard.setVisible(true);
			}
			
		});
		
		
	}

	
	@Override
	public void addZoneOptions(GWT_Zone[] zones) {
		ccForm.setStateOptions(zones);
	}


	//The data has been verified on the client and therefore the cardMap can be updated
	@Override
	public GWT_CreditCard getCard(String id) {
		return ccForm.getCard(Integer.parseInt(id));
	}


	@Override
	public HasClickHandlers addCard() {
		return addCard;
	}

	@Override
	public void showAddCardDialog() {
		addCardDiv.insert(ccForm,0);
		ccForm.clearCard();
		ccForm.setVisible(true);
		addCard.setVisible(false);
		addCardDiv.setVisible(true);
		
		insertCard.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				JQuery.fadeOutErrors();
			}
			
		});
		
	}
	
	@Override
	public HasClickHandlers insertCard() {
		return insertCard;
	}

	@Override
	public boolean inserCardErrors() {
		return false;
	}

	@Override
	public GWT_CreditCard getAddCard() {
		return ccForm.getCard(-1);
	}

	@Override
	public boolean editCardErrors() {
		return ccForm.checkRules();
	}

	@Override
	public void showError(String string) {
		ccForm.setError(string);
	}

	@Override
	public void setAsDefault(Integer cardID) {
		this.radioValues.get(String.valueOf(cardID)).setValue(true);
	}



	@Override
	public native void showDefaultCard() /*-{
		$wnd.$(document).ready(function(){
		if($wnd.$('input:radio').length>1)
			$wnd.$('.checkout .saveDefaultDiv').css('display','block');
		else
			$wnd.$('.checkout .saveDefaultDiv').css('display','none');
		});
	}-*/;


	@Override
	public void setContext(String string) {
		this.context=string;
	}


	@Override
	public ArrayList<HasClickHandlers> removeCardHandlers() {
		return removeCardHandlers;
	}


	@Override
	public Map<String,RadioButton> radios() {
		return radioValues;
	}

}
